package com.example.pro5_webflux_r2dbc_book.controllers;

import com.example.pro5_webflux_r2dbc_book.model.Book;
import com.example.pro5_webflux_r2dbc_book.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

//基于函数式编程的方式来实现路由和处理请求的逻辑。
@Component
public class BookHandler {

    @Autowired
    private final BookService bookService;

    public BookHandler(BookService bookService) {
        this.bookService = bookService;
    }

    public Mono<ServerResponse> addBook(ServerRequest request) {
        return request.bodyToMono(Book.class)
                .flatMap(bookService::addBook)
                .flatMap(book -> ServerResponse.ok().body(Mono.just(book), Book.class));
    }

    public Mono<ServerResponse> getAllBooks(ServerRequest request) {
        return ServerResponse.ok().body(bookService.getAllBooks(), Book.class);
    }

    public Mono<ServerResponse> getBookById(ServerRequest request) {
        Long id = Long.valueOf(request.pathVariable("id"));
        return bookService.getBookById(id)
                .flatMap(book -> ServerResponse.ok().body(Mono.just(book), Book.class))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

    public Mono<ServerResponse> updateBook(ServerRequest request) {
        Long id = Long.valueOf(request.pathVariable("id"));
        return request.bodyToMono(Book.class)
                .flatMap(book -> bookService.updateBook(id, book))
                .flatMap(updatedBook -> ServerResponse.ok().body(Mono.just(updatedBook), Book.class))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

    public Mono<ServerResponse> deleteBook(ServerRequest request) {
        Long id = Long.valueOf(request.pathVariable("id"));
        return bookService.deleteBook(id)
                .then(ServerResponse.ok().build());
    }
}


